﻿using System;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Revit;
using YArchitech.Revit.Electric.Common;
using YArchitech.Revit.RevitExtension;

namespace HYRElectric.Dimension
{
	[Regeneration(RegenerationOption.Manual)]
	[Transaction(TransactionMode.Manual)]
	public class CmdWireTagInsert : YJKCommandManual
	{
		protected override Result YJKExcute(ExternalCommandData cmdData, ref string message, ElementSet elements)
		{
			DlgWireTagInsert dlgWireTagInsert = new DlgWireTagInsert(cmdData.Application);
			dlgWireTagInsert.Show(WindowHelper.HWndRevit);
			WindowHelper.SendMessageToWndRevit();
			Result result;
			try
			{
                ISelectionFilter selectionFilter = new ElectricDim.WireFilter();
				Selection selection = cmdData.Application.ActiveUIDocument.Selection;
				for (;;)
				{
					Reference reference = selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, selectionFilter, "请选择要标注的导线");
					if (reference != null)
					{
						Wire wire = this.m_doc.GetElementById(reference.ElementId) as Wire;
						Family family = dlgWireTagInsert.SelectDbFamily.Load(this.m_doc);
						if (family == null)
						{
							break;
						}
						FamilySymbol familySymbol = null;
						foreach (FamilySymbol familySymbol2 in family.GetSymbols())
						{
							if (familySymbol2 != null)
							{
								familySymbol = familySymbol2;
								break;
							}
						}
						if (familySymbol == null || familySymbol.Id == null)
						{
							goto IL_D4;
						}
						this.StartTransaction();
						this.AddWireShareParam(wire, cmdData.Application.ActiveUIDocument.Document);
						WireDimension.DeleteLeadLineGroups(this.m_doc, wire, "导线回路标记引线ID");
						this.DeleteWireTag(wire);
						this.SetParamter(wire, dlgWireTagInsert.TagText);
						if (dlgWireTagInsert.cbxLeadDim.Checked)
						{
							XYZ pickPoint = selection.PickPoint("请点选标注位置");
							this.CreatWireTag(cmdData.Application.ActiveUIDocument, reference, pickPoint, familySymbol);
						}
						else
						{
							IndependentTag independentTag = this.m_uiDoc.Document.Create.NewTag(this.m_uiDoc.ActiveView, wire, false, 0, 0, reference.GlobalPoint);
							independentTag.ChangeTypeId(familySymbol.Id);
							this.SetParamter(independentTag.GetTypeId());
							wire.GetParameter("导线回路标记引线ID").Set("");
						}
						this.CommitTransaction();
					}
				}
				dlgWireTagInsert.Close();
				return Autodesk.Revit.UI.Result.Failed;
				IL_D4:
				dlgWireTagInsert.Close();
				result = Autodesk.Revit.UI.Result.Failed;
			}
			catch (Exception)
			{
				this.RollbackTransaction();
				dlgWireTagInsert.Close();
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			return result;
		}

		private void CreatWireTag(UIDocument uiDoc, Reference refer, XYZ pickPoint, FamilySymbol fs)
		{
			Document document = uiDoc.Document;
			View activeView = document.ActiveView;
			XYZ xyz = new XYZ(1.0, 0.0, 0.0);
			XYZ globalPoint = refer.GlobalPoint;
			Wire wire = uiDoc.Document.GetElement(refer) as Wire;
			pickPoint = new XYZ(pickPoint.X, pickPoint.Y, globalPoint.Z);
			IndependentTag independentTag = document.Create.NewTag(activeView, wire, false, 0, 0, pickPoint);
			independentTag.ChangeTypeId(fs.Id);
			BoundingBoxXYZ boundingBoxXYZ = independentTag.get_BoundingBox(document.ActiveView);
			Line line = YJKLineEx.YJKGetBound(new XYZ(boundingBoxXYZ.Min.X, boundingBoxXYZ.Min.Y, 0.0), new XYZ(boundingBoxXYZ.Max.X, boundingBoxXYZ.Min.Y, 0.0));
			YJKLineEx.YJKGetBound(new XYZ(boundingBoxXYZ.Max.X, boundingBoxXYZ.Min.Y, 0.0), new XYZ(boundingBoxXYZ.Max.X, boundingBoxXYZ.Max.Y, 0.0));
			XYZ xyz2 = (new XYZ(boundingBoxXYZ.Max.X, boundingBoxXYZ.Max.Y, 0.0) - new XYZ(boundingBoxXYZ.Max.X, boundingBoxXYZ.Min.Y, 0.0)) / 2.0;
			if (pickPoint.X < globalPoint.X)
			{
				xyz = new XYZ(-1.0, 0.0, 0.0);
			}
			ElementId elementId = WireDimension.CreatLeadLine(uiDoc, wire, globalPoint, pickPoint, xyz, line.Length, true);
			XYZ xyz3 = (pickPoint + (pickPoint + line.Length * xyz)) / 2.0;
			ElementTransformUtils.MoveElement(document, independentTag.Id, xyz3 - pickPoint);
			ElementTransformUtils.MoveElement(document, independentTag.Id, xyz2);
			wire.GetParameter("导线回路标记引线ID").Set(elementId.ToString());
		}

		private void AddWireShareParam(Wire wire, Document doc)
		{
			Dictionary<string, ParameterType> dictionary = new Dictionary<string, ParameterType>();
            dictionary.Add("导线回路标记引线ID", (ParameterType)1);
			foreach (KeyValuePair<string, ParameterType> keyValuePair in dictionary)
			{
				if (wire.GetParameter(keyValuePair.Key) == null)
				{
					YArchitech.Revit.Electric.Common.SharedParameter.InsertSharedParameter(doc, BuiltInCategory.OST_Wire, "电气数据", dictionary, false);
					break;
				}
			}
		}

		private void StartTransaction()
		{
			this.m_trans = new Transaction(this.m_doc, "导线回路标注");
			this.m_trans.Start();
		}

		private void CommitTransaction()
		{
			if (this.m_trans != null)
			{
				this.m_trans.Commit();
			}
		}

		private void RollbackTransaction()
		{
            if (this.m_trans != null && this.m_trans.GetStatus() == (TransactionStatus)1)
			{
				this.m_trans.RollBack();
			}
		}

		private void DeleteWireTag(Element element)
		{
			if (element == null)
			{
				return;
			}
			BuiltInCategory category = BuiltInCategory.OST_WireTags;
			List<string> list = new List<string>();
			list.Add("导线回路标记");
			List<Element> list2 = DimensionUtil.ElementTags(this.m_doc, element, category, list);
			if (list2 == null || list2.Count == 0)
			{
				return;
			}
			foreach (Element element2 in list2)
			{
				this.m_doc.Delete(element2.Id);
			}
			this.m_doc.Regenerate();
		}

		private void SetParamter(Wire wire, string text)
		{
			if (wire == null || text.Length == 0)
			{
				return;
			}
			if ("<默认>" == text)
			{
				Parameter parameter = wire.get_Parameter(BuiltInParameter.RBS_ELEC_WIRE_CIRCUITS);
				wire.get_Parameter(BuiltInParameter.DOOR_NUMBER).Set(parameter.AsString());
				return;
			}
			wire.get_Parameter(BuiltInParameter.DOOR_NUMBER).Set(text);
		}

		private void SetParamter(ElementId id)
		{
			FamilySymbol familySymbol = this.m_doc.GetElementById(id) as FamilySymbol;
			if (familySymbol == null)
			{
				return;
			}
			Parameter parameter = familySymbol.GetParameter("标记类别");
			if (parameter == null)
			{
				return;
			}
			if (parameter.AsString() != "导线回路标记")
			{
				parameter.Set("导线回路标记");
			}
		}

		private Transaction m_trans;
	}
}
